﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.ManagementConsole;
using SharpShare.Configuration;
using System.ComponentModel;

namespace SharpShare.Management.Mmc.Nodes {
    public class SharpShareNode : ScopeNode, IExtensionInstanceSelector<ServiceElement>, IExtensionInstanceSelector<StorageProviderElement> {
        private Exception _connectionException;
        private List<MessageView> _visibleMessageViews = new List<MessageView>();

        public SharpShareNode() {
            this.DisplayName = "SharpShare";
            this.ImageIndex = 1;
            this.SelectedImageIndex = 1;
            this.EnabledStandardVerbs = StandardVerbs.Refresh;
        }

        public Exception ConnectionException {
            get {
                return _connectionException;
            }
            set {
                _connectionException = value;

                this.Refresh();
            }
        }

        private void Refresh() {
            this.Children.Clear();
            this.ViewDescriptions.Clear();

            SharpShareSnapIn snapIn = (SharpShareSnapIn)this.SnapIn;
            List<ScopeNode> children = new List<ScopeNode>();

            if (this.ConnectionException == null) {
                var servicesNode = new ServicesNode(snapIn.ServiceFactory) {
                    DisplayName = "Services",
                    ImageIndex = (int)Icon.Services,
                    SelectedImageIndex = (int)Icon.Services,
                    InstanceSelector = this
                };
                children.Add(servicesNode);

                var storageProvidersNode = new StorageProvidersNode(snapIn.StorageProviderFactory) {
                    DisplayName = "Storage Providers",
                    ImageIndex = (int)Icon.Storage,
                    SelectedImageIndex = (int)Icon.Storage,
                    InstanceImageIndex = (int)Icon.StorageGold,
                    InstanceSelector = this
                };
                children.Add(storageProvidersNode);

                var sessionsNode = new ScopeNode(true) {
                    DisplayName = "Sessions",
                    ImageIndex = (int)Icon.User,
                    SelectedImageIndex = (int)Icon.User
                };
                sessionsNode.ViewDescriptions.Add(new MmcListViewDescription(MmcListViewOptions.ExcludeScopeNodes) {
                     DisplayName = "Sessions",
                     ViewType = typeof(Views.SessionsListView)
                });
                sessionsNode.ViewDescriptions.DefaultIndex = 0;

                children.Add(sessionsNode);

                var openFilesNode = new ScopeNode(true) {
                    DisplayName = "Open Files",
                    ImageIndex = (int)Icon.Files,
                    SelectedImageIndex = (int)Icon.Files
                };
                openFilesNode.ViewDescriptions.Add(new MmcListViewDescription(MmcListViewOptions.None | MmcListViewOptions.ExcludeScopeNodes) {
                    DisplayName = "Open Files",
                    ViewType = typeof(Views.OpenFilesListView)
                });
                openFilesNode.ViewDescriptions.DefaultIndex = 0;

                children.Add(openFilesNode);
            } else {
                this.ViewDescriptions.Add(new MessageViewDescription() {
                    DisplayName = "Error Details",
                    Title = "Unable to connect to SharpShare service.",
                    BodyText = string.Format("The SharpShare service could not be contacted. Make sure the service is running and select 'Refresh' to try again.\r\n\r\n{0}", this.ConnectionException),
                    IconId = MessageViewIcon.Error,
                    ViewType = typeof(ErrorMessageView)
                });
                this.ViewDescriptions.DefaultIndex = 0;
            }

            this.Children.AddRange(children.ToArray());

            if (_visibleMessageViews.Count > 0) {
                _visibleMessageViews[0].SelectScopeNode(this);
            }
        }

        protected override void OnExpand(AsyncStatus status) {
            base.OnExpand(status);

            this.Refresh();
        }
        protected override bool OnExpandFromLoad(SyncStatus status) {
            return true;
        }
        protected override void OnRefresh(AsyncStatus status) {
            base.OnRefresh(status);

            ((SharpShareSnapIn)this.SnapIn).RefreshConfiguration();
        }

        #region IExtensionInstanceSelector<ServiceElement> Members

        object IExtensionInstanceSelector<ServiceElement>.GetInstance(ServiceElement extension) {
            return new ConfigurationElementTypeDescriptor(TypeDescriptor.GetProvider(extension).GetTypeDescriptor(extension));
        }

        #endregion

        #region IExtensionInstanceSelector<StorageProviderElement> Members

        object IExtensionInstanceSelector<StorageProviderElement>.GetInstance(StorageProviderElement extension) {
            return new ConfigurationElementTypeDescriptor(TypeDescriptor.GetProvider(extension).GetTypeDescriptor(extension));
        }

        #endregion

        private class ErrorMessageView : MessageView {

            protected override void OnShow() {
                base.OnShow();

                ((SharpShareNode)this.ScopeNode)._visibleMessageViews.Add(this);
            }
            protected override void OnHide() {
                base.OnHide();

                ((SharpShareNode)this.ScopeNode)._visibleMessageViews.Remove(this);
            }
        }
    }
}
